package wortubung.core;

import java.util.HashMap;
import java.util.Map;

import wortubung.WortUbungException;
import wortubung.util.CommonUtils;

public enum POS {
    NOUN(POSCategory.Noun,        "n"),
    NOUN_M(POSCategory.Noun,      "nm", "m"),
    NOUN_F(POSCategory.Noun,      "nf", "f"),
    VERB(POSCategory.Verb,        "v"),
    VERB_T(POSCategory.Verb,      "vt"),
    VERB_I(POSCategory.Verb,      "vi"),
    VERB_B(POSCategory.Verb,      "vb"),
    VERB_PR(POSCategory.Verb,     "vpr"),
    ADJ(POSCategory.Adj,          "adj"),
    ADV(POSCategory.Adv,          "adv"),
    PREP(POSCategory.Prep,        "prep"),
    PRON(POSCategory.Pron,        "pron"),
    CONJ(POSCategory.Conj,        "conj"),
    EXCLAMATION(POSCategory.Excl, "excl"),
    IDIOM(POSCategory.Fixed,      "idiom"),
    SLANG(POSCategory.Fixed,      "slang"),
    LOCUTION(POSCategory.Fixed,   "loc"),
    ;

    private POSCategory category;
    private String[] shortName;

    POS(POSCategory cat, String... shortName) {
        this.category = cat;
        this.shortName = shortName;
    }

    public String[] getShortNames() { return shortName; }
    public String getShortName() { return CommonUtils.isEmpty(shortName) ? null : shortName[0]; }

    private static Map<String,POS> shortNameMap = new HashMap<String,POS>();
    static {
        for (POS p : values())
            for (String sn : p.getShortNames())
                 shortNameMap.put(sn, p);
    }

    public static POS fromShortName(String shortName) {
        POS ret = (shortName == null) ? null : shortNameMap.get(shortName);
		if (ret == null)
		    throw new WortUbungException("Invalid POS short name: '" + shortName + "'.");
		return ret;
    }

    public POSCategory getCategory() { return category; }

    public boolean isNoun() { return name().startsWith("NOUN"); }
    public boolean isVerb() { return name().startsWith("VERB"); }
    public boolean isReflexiveVerb() { return this == VERB_PR; }
    public boolean isSmallWord() { return this == CONJ || this == PREP || this == PRON; }
    public boolean isFixedUsage() { return this == IDIOM || this == LOCUTION || this == SLANG; }

    public GENDER getGender() {
    	switch(this) {
    	case NOUN:   return GENDER.n;
    	case NOUN_M: return GENDER.m;
    	case NOUN_F: return GENDER.f;
    	default:     return null;
    	}
    }
}
